package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentDetailVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentItemVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentQueryVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentSubmitVo;
import com.atguigu.lease.web.admin.vo.fee.FeeValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liubo
 * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service

public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
        implements ApartmentInfoService {
    @Autowired
    private ApartmentInfoMapper apartmentInfoMapper;
    @Autowired
    private GraphInfoMapper graphInfoMapper;
    @Autowired
    private LabelInfoMapper labelInfoMapper;
    @Autowired
    private FacilityInfoMapper facilityInfoMapper;
    @Autowired
    private FeeValueMapper feeValueMapper;


    @Autowired
    private ProvinceInfoMapper provinceInfoMapper;
    @Autowired
    private CityInfoMapper cityInfoMapper;
    @Autowired
    private DistrictInfoMapper districtInfoMapper;

    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private ApartmentLabelService apartmentLabelService;
    @Autowired
    private ApartmentFacilityService apartmentFacilityService;
    @Autowired
    private ApartmentFeeValueService apartmentFeeValueService;



    /**
     * 公寓信息分页查询
     * @param page
     * @param queryVo
     * @return
     */
    @Override
    public IPage<ApartmentItemVo> apartmentPageInfo(IPage<ApartmentItemVo> page, ApartmentQueryVo queryVo) {
        return apartmentInfoMapper.apartmentPageInfo(page, queryVo);
    }

    /**
     * 根据id获取公寓详情信息
     * @param id
     * @return
     */
    @Override
    public ApartmentDetailVo getApartmentDetailVoById(Long id) {
        ApartmentDetailVo apartmentDetailVo = new ApartmentDetailVo();
        //先通过id获取公寓基本信息（单表）
        ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(id);
        BeanUtils.copyProperties(apartmentInfo, apartmentDetailVo);

        //再通过id获取公寓图片信息（一对多）
        List<GraphVo> graphVoList = graphInfoMapper.getApartmentImageById(id);
        apartmentDetailVo.setGraphVoList(graphVoList);

        //再通过id获取公寓标签信息（一对多）
        List<LabelInfo> labelInfoList = labelInfoMapper.getApartmentLabelById(id);
        apartmentDetailVo.setLabelInfoList(labelInfoList);

        //再通过id获取公寓配套设施信息（一对多）
        List<FacilityInfo> facilityInfoList = facilityInfoMapper.getApartmentFacilityById(id);
        apartmentDetailVo.setFacilityInfoList(facilityInfoList);

        //再通过id获取公寓杂费信息（一对多）
        List<FeeValueVo> feeValueVoList = feeValueMapper.getApartmentFeeById(id);
        apartmentDetailVo.setFeeValueVoList(feeValueVoList);
        return apartmentDetailVo;
    }

    /**
     * 保存或更新公寓信息
     * @param apartmentSubmitVo
     */
    @Override
    @SneakyThrows
    public void saveOrUpdateApartmentSubmitVo(ApartmentSubmitVo apartmentSubmitVo) {
        //先获取公寓的id,因为增没有id，改有id
        Long id = apartmentSubmitVo.getId();
        //不管是增还是删，先把省市区三级信息给查出来,并存到vo中
        String provinceName = provinceInfoMapper.selectById(apartmentSubmitVo.getProvinceId()).getName();
        apartmentSubmitVo.setProvinceName(provinceName);
        String cityName = cityInfoMapper.selectById(apartmentSubmitVo.getCityId()).getName();
        apartmentSubmitVo.setCityName(cityName);
        String districtName = districtInfoMapper.selectById(apartmentSubmitVo.getDistrictId()).getName();
        apartmentSubmitVo.setDistrictName(districtName);
        // 把公寓的基本信息放进去
        this.saveOrUpdate(apartmentSubmitVo);


        //如果是改，则公寓的图片信息、标签信息和配套设施信息、杂费信息都需要更新，我们常用的方法是把原有的信息全部删除，在新增的时候，顺便把新的信息也加进去
        if (id != null) {
            //把公寓的图片信息、标签信息和配套设施信息、杂费信息全部删除
            graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemId, id).eq(GraphInfo::getItemType, ItemType.APARTMENT));//这里要删除公寓的图片信息，所以这里的itemType要和公寓的图片类型一致
            apartmentLabelService.remove(new LambdaQueryWrapper<ApartmentLabel>().eq(ApartmentLabel::getApartmentId,id));
            apartmentFacilityService.remove(new LambdaQueryWrapper<ApartmentFacility>().eq(ApartmentFacility::getApartmentId,id));
            apartmentFeeValueService.remove(new LambdaQueryWrapper<ApartmentFeeValue>().eq(ApartmentFeeValue::getApartmentId,id));
        }

        //现在重新新增公寓的图片信息、标签信息和配套设施信息、杂费信息
        //从前端传递的vo中获取配套信息的所有id
        List<Long> facilityInfoIds = apartmentSubmitVo.getFacilityInfoIds();
        //定义一个配套信息的集合，用来存放每一个配套信息
        List<ApartmentFacility> apartmentFacilities = new ArrayList<>();
        //遍历id集合，把每一个配套信息封装到apartmentFacility对象中
        facilityInfoIds.forEach(facilityInfoId -> {
            ApartmentFacility apartmentFacility =ApartmentFacility.builder().apartmentId(apartmentSubmitVo.getId()).facilityId(facilityInfoId).build();
            //把每一个配套信息封装到apartmentFacility对象中，并存入集合中
            apartmentFacilities.add(apartmentFacility);
        });
        //新增配套信息到数据库中
        apartmentFacilityService.saveBatch(apartmentFacilities);//这个方法是批量新增的方法，把集合中的所有对象都存入数据库中


        //同样的方法新增标签信息
        List<Long> labelInfoIds = apartmentSubmitVo.getLabelIds();
        List<ApartmentLabel> apartmentLabels = new ArrayList<>();
        labelInfoIds.forEach(labelInfoId -> {
            ApartmentLabel apartmentLabel = ApartmentLabel.builder().apartmentId(apartmentSubmitVo.getId()).labelId(labelInfoId).build();
            apartmentLabels.add(apartmentLabel);
        });
        apartmentLabelService.saveBatch(apartmentLabels);
        //杂费
        List<Long> feeValueIds = apartmentSubmitVo.getFeeValueIds();
        List<ApartmentFeeValue> apartmentFeeValues = new ArrayList<>();
        feeValueIds.forEach(feeValueId -> {
            ApartmentFeeValue apartmentFeeValue = ApartmentFeeValue.builder().apartmentId(apartmentSubmitVo.getId()).feeValueId(feeValueId).build();
            apartmentFeeValues.add(apartmentFeeValue);
        });
        apartmentFeeValueService.saveBatch(apartmentFeeValues);
        //图片信息
        List<GraphVo> graphVoList = apartmentSubmitVo.getGraphVoList();
        List<GraphInfo> graphInfos = new ArrayList<>();
        graphVoList.forEach(graphVo -> {
            GraphInfo graphInfo = new GraphInfo();
            graphInfo.setName(graphVo.getName());
            graphInfo.setUrl(graphVo.getUrl());
            graphInfo.setItemId(apartmentSubmitVo.getId());
            graphInfo.setItemType(ItemType.APARTMENT);
            graphInfos.add(graphInfo);
        });
        graphInfoService.saveBatch(graphInfos);


    }

    /**
     * 根据id删除公寓信息
     * @param id
     */
    @Override
    public void removeAparrtmentInfoById(Long id) {
        //先把基本信息干掉
        this.removeById(id);
        //再把其他复杂信息干掉
        graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemId, id).eq(GraphInfo::getItemType, ItemType.APARTMENT));//这里要删除公寓的图片信息，所以这里的itemType要和公寓的图片类型一致
        apartmentLabelService.remove(new LambdaQueryWrapper<ApartmentLabel>().eq(ApartmentLabel::getApartmentId,id));
        apartmentFacilityService.remove(new LambdaQueryWrapper<ApartmentFacility>().eq(ApartmentFacility::getApartmentId,id));
        apartmentFeeValueService.remove(new LambdaQueryWrapper<ApartmentFeeValue>().eq(ApartmentFeeValue::getApartmentId,id));

    }
}




